\documentclass[11pt]{article}
\author{Ivan Bogouchev \and Ognian Pertchev \and Gueorgui Tzotchev}
\usepackage[latin1]{inputenc}
\usepackage[francais]{babel}
\usepackage{graphicx}
\usepackage{verbatim}
\title{FOGE2 le retour}
\frenchspacing
\begin{document}
\maketitle

\pagebreak
\tableofcontents
\pagebreak

\section{Présentation du TER}

\subsection{Introduction (Foge d'origine)}

FOGE est une librairie Perl, dédiée à la gestion de questionnaires,
destinés pour le WEB. La version d'origine était écrite par Christian
Queinnec pour faciliter le déploiement de questionnaires d'évaluation
des enseignements. Par la suite, deux étudiants - Rémi Bantos et David
Haguenauer ont fait une réécriture orientée objet visant à rendre la
librairie modulaire, facilitant l'ajout de nouvelles fonctionnalités.

FOGE propose aux créateurs de questionnaires les objets et
fonctionnalités suivantes:

\begin{enumerate}
\item objets représentant des questions: selon sa nature une question peut
être représentée sous forme d'un menu, d'un groupe de cases à cocher
(ou boutons radio) ou d'un textfield (ou textarea).

\item objets représentant des sections - une section dans le vocabulaire
FOGE est une collection de questions, utilisée pour regrouper des
questions concernant le même sujet.

\item objets représentant le formulaire - un formulaire dans le
vocabulaire FOGE est une collection de sections. Le formulaire est
l'objet principal d'un questionnaire, capable de servir la page HTML
du questionnaire, insérer les réponses dans une base de données,
analyser les réponses pour en extraire des statistiques.

\item objets représentant des statistiques associées au questions,
sections et formulaires, proposant plusieurs types de statistiques
(histogrammes, camemberts, ...) choisies par le concepteur du
questionnaire.

\item gestion des droits d'effectuer certaines actions (visualiser le
questionnaire, répondre, voir des différent type de statistiques) en
fonction de la date courante, l'adresse ip de l'utilisateur ...

\end{enumerate}

Du point de vue des utilisateurs, FOGE offre les fonctionnalités
suivantes: 

\begin{enumerate}
\item générer la page HTML visualisant le questionnaire en respectant la
norme HTML4 et utilisant les CSS. Les messages produits par FOGE (tels
que les noms des boutons, les messages d'erreur, la confirmation de
réception d'une réponse au questionnaire) peuvent être traduits
automatiquement par FOGE. 

\item créer les tables SQL nécessaires pour le stockage des réponses.

\item insérer dans la base de données la \emph{soumission} (par
'soumission' on entend l'ensemble des réponses d'un utilisateur au
questionnaire) en veillant à ce que les réponses respectent les
contraintes définies dans le questionnaire:
  \begin{enumerate}
  \item droit de répondre (ip, utilisateur, date ....)
  \item réponses au questions obligatoires
  \item réponses conformes (à une expression régulière par ex.)
  \end{enumerate}

\item extraire des diverses statistiques sur la répartition des
réponses. (dans FOGE2 les statistiques sont choisies par le concepteur
du questionnaire).

\end{enumerate}

\centerline{\includegraphics{formulaire}}
\subsection{But du TER}
Le but principal de notre projet est d'étendre les fonctionnalités de
FOGE, pour permettre aux concepteurs d'un questionnaire d'effectuer
des sondages encore plus exhaustives, de rajouter des outils
statistiques permettant une analyse des données plus sophistiquée et
d'étendre les possibilités de définition des droits d'accès au
formulaire et aux statistiques.

On a donc rajouté les fonctionnalités suivantes, décrites dans la
section 2: 

\begin{description}

\item[filtres] - un filtre permet de restreindre l'ensemble des
informations, extraites de la base de données. La restriction se fait
en ne gardant que les réponses associées à une soumission, conforme à
certains critères. (Il s'agit d'une réduction du nombre de n-uplets
dans les relations contenant les réponses).

\item[vues] - une vue permet de restreindre l'ensemble des
  questions. L'utilisateur définit une vue, en choisissant les
  questions, dont les réponses l'intéressent. (Réduction du nombre de
  colonnes des relations).

\item[consultation fiche-par-fiche] - une fiche représente l'ensemble
des réponses d'un étudiant au questionnaire. La consultation du vote
fiche-par-fiche exploite les sous-ensembles définis après filtrage et
construction de la vue.

\item[sécurité] - concentrer la gestion des droits d'accès dans un module
dédié à cet effet. Définir formellement les différents types
d'utilisateurs, groupes d'utilisateurs, ainsi que leurs droits.

\item[nouvelles statistiques] - les statistiques dédiées à la
recherche d'interdépendances entre les réponses des différentes
questions. 

\item[nouveaux type de questions] - liées logiquement (prendre en
  compte la réponse à une des questions seulement si la réponse à
  telle autre question est conforme à certains critères.

\item[choisir les statistiques au moment de la consultation] - permettre à
un utilisateur de choisir les statistiques qui lui conviennent, au moment
de la consultation.

\item[statut] - cette fonctionnalité permet la consultation des
  paramètres d'un questionnaire et son état actuel: la date
  d'activation, la date limite (le temps qui reste pour remplir le
  questionnaire), le nombre de soumissions dans la base de donnée au
  moment de la demande de statu.

\item[adaptation] - adapter les parties existantes afin d'utiliser les
  nouvelles fonctionnalités: filtrage, vues, sécurité

\end{description}



\section{Les nouvelle fonctionnalités en détails}

Pour décrire en détails les extensions apportées, expliquons
brièvement comment un script FOGE accomplit ses fonctions de base
(servir la page HTML du questionnaire, insérer les réponses dans la
base de données et afficher les statistiques).

Un script FOGE est un script CGI. En tant que tel, il est
lancé par le serveur WEB et reçoit dans son environnement plusieurs
informations (le query string des méthodes GET et POST de HTTP, l'ip
d'où le formulaire a été invoqué ...).

Après avoir construit toutes les questions et sections ainsi que le
formulaire les contentant, le script FOGE invoque la méthode
\emh{main()} du formulaire.

Après extraction et analyse des arguments du query string, le
formulaire exécute l'action demandée. Les méthodes correspondant aux
différentes actions sont \emph{serve()} (pour servir la page),
\emph{handle_submission()} (pour gérer la soumission) etc.

Quelle que soit l'action demandée, une partie du travail est effectuée
par l'objet représentant le formulaire, qui de son côté confie le
reste du travail aux sections. De même,
après avoir effectué une partie du travail la concernant, la section
distribue le reste du travail aux questions qu'elle contient.

Cette approche modulaire permet de structurer le code et facilite
l'ajout de nouvelles fonctionnalités.

\subsection{Filtres}

Le procédé de filtrage est un outil qui permet de rechercher
avec plus de précisions les informations qui nous intéressent et de
mettre en évidence des résultats qui vont permettre par la suite
d'exploiter mieux les statistiques obtenues.
Les filtres diminuent l'ensemble de recherche, et montrent les
corrélations entre les différentes questions.
Le choix de filtres va affecter la manière dont les statistiques vont
être calculées. De ce choix dépend, en grande partie, la perception
des résultats.

Un filtre est un objet qui se place entre la base de données et les
parties de FOGE qui en extraient des informations (statistiques,
consultations fiche-par-fiche). Il permet de construire des statistiques
pour un sous-ensemble des réponses du questionnaire. Ce sous-ensemble
correspond à certains critères, choisis par l'utilisateur au moment de
la consultation des statistiques.

\subsubsection{Différents types de filtres}

Les différents types de filtres choisissent les sous-ensembles associés
selon des critères différents. On a implémenté deux filtres:

Le premier filtre permet de choisir les soumissions, en fonction des
adresses ip d'origine. Par exemple, étant donné un questionnaire
concernant les étudiants du campus Jussieu, on aimerait pouvoir
distinguer les soumissions provenant de l'intranet de l'UPMC et celles
provenant de Paris 7.

Le deuxième filtre, permet de choisir les soumissions, ayant donné
telle ou telle réponse à une, plusieurs ou à la totalité des
questions. Cela permet de voir la répartition des
réponses dans la sous-ensemble qui satisfait les critères de
filtrage. 

\subsubsection{Constructions des filtres}

Le critère de filtrage, pour le FilterIP est une chaîne décrivant une
adresse ip, où on peut utiliser le caractère '*' pour signifier un
groupe d'adresses ip. Par exemple pour les machines du CCE on
pourrait utiliser le filtre construit à l'aide de "134.157.116.*".

Pour construire le filtre template, FOGE sert à l'utilisateur qui veut
filtrer, la page HTML du questionnaire, telle qu'elle serait servie à
un étudiant pour remplir le questionnaire, mais avec quelques légères
modifications: 
\begin{itemize}
  \item le questions à choix unique sont devenus des questions à
choix multiples.
  \item la réponse à toutes les questions est facultative
\end{itemize}

\centerline{\includegraphics{filtre}}

Donc l'utilisateur répondra au parties du questionnaire qui
l'intéressent, pour construire un filtre qui va sélectionner de la
base de données seulement les soumissions, qui correspondant à la
façon dont l'utilisateur à rempli le questionnaire de construction du
filtre. 


\subsubsection{Implémentation}

Pour chaque soumission FOGE stocke dans une table SQL ("foge\_answer") un
identificateur de la soumission, l'adresse ip et le nom du
questionnaire. Pour chaque section du questionnaire, il existe une
table SQL, qui contient les réponses aux questions de la section. Le
premier attribut de cette relation est un identificateur référençant
l'identificateur de la table "foge\_answer". Ainsi pour avoir les
réponses qu'un étudiant a faites (et ensuite calculer les statistiques
dessus), on fait la jointure entre la table foge\_answer, et les tables
des sections su l'attribut id.
Donc pour filtrer, il nous suffit de garder dans la table foge\_answer
(en effet, on crée un table temporaire, qui masque foge\_answer) les
soumissions qui correspondent aux critères de filtrage.

Par exemple pour avoir toutes les soumissions, qui ont répondu 'oui' à
la question 'Question1' de la section 'Section1', on définit la table
suivante:

\begin{verbatim}
CREATE TEMP TABLE foge\_answer
SELECT f.*
FROM foge\_answer f, Section1 s
WHERE f.enquiry="Poll" and f.id = s.id and s.Q1 = "oui";
\end{verbatim}

Donc le critère de filtrage est traduit en une expression WHERE du
langage SQL.


\subsection{Vues}

Une vue donne accès à un sous-ensemble des questions. Elle
permet de présenter à l'utilisateur (et au programmeur) différentes
perspectives du même questionnaire. Son utilité se manifeste, surtout
lors du dépouillement des statistiques à des questionnaire longs, en
permettant de choisir de voir des statistiques sur une (petite) partie
des questions.

Après avoir définit la vue qui l'intéresse, l'utilisateur peut
visualiser les statistiques, consulter les réponses aux questionnaire
fiche par fiche, ou décider de définir un filtre. En tout les cas les
fonctionnalités offertes par FOGE, utiliseront l'ensemble des questions
définies dans la vue et non celles définies dans le formulaire.


\subsubsection{Construction des vues}

On a implémenté deux façons de construire une vue. 

La première consiste à afficher la liste des questions du
formulaire, groupées par section et de donner à l'utilisateur la
possibilité de choisir celles qui l'intéressent (à l'aide de cases à
cocher, affichées à coté des titres des questions).
Initialement toutes les cases sont choisies.


\centerline{\includegraphics{viewgen}}

L'utilisateur peut sélectionner les cases associées aux questions
qui ne l'intéressent pas ou directement décider qu'il n'est pas intéressé par
toutes les questions d'une section et donc décocher la case
correspondant à la section.


La deuxième façon de définir une vue est intégrée à la consultations
des statistiques associées aux questions. Après avoir affiché la page des
statistiques pour les questions actuellement choisies, l'utilisateur
peut diminuer l'ensemble des questions (toujours à l'aide de cases à
cocher) et réafficher la page des statistiques. Càd l'affichage des
statistiques et la définition de la vue sont fait dans la même page HTML.

\centerline{\includegraphics{statsnviews}}

\subsubsection{Implémentation des vues}

Une vue est un objet PERL, défini dans le module View.pm. Un objet vue
est capable d'initialiser les attributs qui choisissent les questions
importantes, depuis les arguments passés au script par la méthode
POST. Une fois ses attributs initialisés, l'objet est capable
d'affirmer quelles sections et questions font partie de la vue (à
travers les méthodes contains\_question() et contains\_section()).

Donc désormais, avant de déléguer certaines actions à une de ses
sections, le formulaire vérifie que la section fait partie de la vue
que l'utilisateur a créée, en invoquant la méthode contains\_section()
de la vue. De même pour les sections, avant de déléguer des actions à
une question, la section vérifie que la question appartient à la vue.


(Est-ce que une partie du code d'initialisation de la vue est
convenable ici?)


(Est-ce que une partie du code montrant l'appel des méthodes serve(),
handle\_submission(), etc des sections par le formulaire et des questions
par les sections est convenable ici)


\subsection{Fiche par Fiche}

La consultation fiche-par-fiche des réponses aux
questionnaire nous permet de voir comment un utilisateur (un étudiant)
a rempli la totalité du questionnaire. 

La visite des réponses fiche par fiche est conçue afin d'exploiter
les fonctionnalités offertes par les filtres et les vues: càd
l'ensemble des fiches sera composé seulement des réponses qui
satisfont au critères définis dans le filtre et chaque fiche
contiendra seulement les réponses aux questions choisies par la vue.

\subsubsection{Comment consulter les réponses}

L'examen du vote fiche par fiche est implémenté comme une nouvelle
action effectué par le formulaire. Donc il suffit d'invoquer le script
avec l'argument CGI ``action=fpf''. Bien
évidemment on peut avoir déjà défini un filtre et/ou une vue.

\subsection{Nouvelles statistiques}
On a rajouté un nouveau type de statistiques à la batterie de
statistiques que FOGE proposait déjà - les stats croisées
(StatsCrossed.pm). Ce type de statistiques est conçu pour mettre à
l'évidence les interdépendances (ou montrer qu'il n'y en a pas) des
réponses à une question en fonction des réponses à une autre question.

\subsubsection{Interprétation de l'information fournie par les StatsCrossed}

\subsubsection{Implémentation (Dépendance du module GD)}


\subsection{Choix dynamique des statistiques}

Il s'agit de donner à l'utilisateur la possibilité de choisir et
reconfigurer les statistiques affichées lors de leur
consultation. Cela nous permet de choisir les statistiques en fonction de la
répartition des réponses. Des fois un camembert dit plus qu'un
histogramme.

\subsubsection{Implémentation}



\subsection{La sécurité de FOGE}
FOGE est créé en raison d'être utilisé à travers des réseaux TCP/IP,
internet en général, et comme toute application exposée à manipulation
d'une publique importante, il doit être bien protégé, c-à-d ne pas
laisser la possibilité à une personne n'ayant pas les droits
nécessaires de corrompre les données et l'application elle-même.

Avant, les modules de FOGE assuraient une distinction basique des
types d'utilisateurs. Les vérifications d'identité se faisaient dans
le module Form qui en général avait pour but de construire le
formulaire et de traiter les différents types d'actions que le
questionnaire proposait. Bref, le processus d'identification n'étaient
que quelques petites fonctions dans le module Form qui vérifiaient que
l'adresse IP appartenait à un certain groupe autorisé. Ces fonctions
ne prenaient pas en compte le type de l'action demandée, elles
retournaient ou "mourraient"...

L'extension dans cet aspect de FOGE consiste en un nouveau module,
nommé SecurityAgent, ayant pour but d'étendre les possibilités de
définition des droits d'accès et de s'occuper des permissions des
usagers pendant les trois différentes étapes de la durée de vie d'un
questionnaire.

L'organisation des droits d'accès est réalisée d'une manière un peu
semblable à celle d'unix, c-à-d une fois connecté un utilisateur est
authentifié soit comme un utilisateur connu, soit comme faisant partie
d'une ou plusieurs groupes, chacun avec des droits spécifiques. Ainsi
le créateur du questionnaire peut spécifier les droits d'accès pour
chaque adresse IP et/ou chaque utilisateur authentifié par un login et
mot de passe, ces derniers obtenus à l'aide du protocole https, ou
simplement par une clé de vote, qui assurera l'anonymat du client et
ses réponses uniques (c-à-d qu'il n'a pas répondu qu'une seule fois).

En général il existent trois types d'usagers : - personne(s) avec des
droits d'administration (tous les droits) - personnes qui posent les
questions; eux ayant la possibilité de consulter certaines ou toutes
les statistiques avant la date limite des soumissions.  - personnes
dont on veut l'opinion. (il se peut que la même personne possède 2
différentes identités pour le formulaire - par exemple dans le cas
d'un formulaire ayant pour but de prévoir les résultats des élections,
le créateur du formulaire voudrait voter lui-aussi..)

La durée de vie d'un questionnaire étant limitée en général, on
distingue trois étapes de l'existence d'un questionnaire :

Étape 1 : Le questionnaire est mis au point, mais il n'est pas encore
autorisé à son audience à soumettre des réponses. Seules certaines
personnes ont le droit de consulter et éventuellement d'apporter des
modifications au formulaire.  Ex. : Un professeur pourrait vouloir
ajouter une question portant sur l'examen final au formulaire
d'évaluation de la maîtrise, mais lors de la création du formulaire
l'examen n'est pas encore prêt... Les modifications online ne sont pas
(encore) implémentés.  Étape 2 : Le questionnaire est disponible aux
soumissions. Pendant ce temps les différents utilisateurs pourront
voir les réponses, les statistiques simples, les statistiques avancées
ou ne rien voir, dépendant de leurs droits d'accès.  Étape 3 : Les
soumissions finies, le formulaire est disponible aux analyses, mais
encore pas tous ont le droit de voir les réponses à toutes les
questions.

La raison la plus importante d'apporter les modifications en créant ce
module n'est pas la besoin d'avoir un système avancé d'identification,
mais la complexité de la manière de choisir quel utilisateur peut voir
quoi et dans quelle période. Les droits d'un utilisateur peuvent
changer lors des trois étapes de l'existence d'un questionnaire donné,
tandis que les droits d'un autre utilisateur du même type (voir types
plus haut) peuvent rester les mêmes ou changer différemment. Et même
si cela peut paraître rarement nécessaire, il y a des cas où une telle
flexibilité aidera à favoriser des questions dont l'on ne voudrait pas
exposer les réponses qu'à un certain groupe d'utilisateurs seulement.

Ayant séparé de cette manière le processus d'évaluation des droits
d'accès de la construction du formulaire rend la configuration des
droits facilement extensible et mieux paramétrable.




\subsubsection{Comment définir les droits d'accès?}
Les droits d'accès sont définis dans le script de génération du
questionnaire lui-même, de manière qu'ils sont figés dedans pour toute
la vie du questionnaire. Ils sont structurés sous forme de hachages et
tableaux imbriqués.  En général les droits se définissent en créant
une instance du module SecurityAgent. Cette instance s'initialise avec
les droits spécifiés comme arguments. Son constructeur la remplit avec
le reste des données nécessaires pour calculer quelles sont les
actions permises pour un utilisateur donné à un instant donné.  Il y
trois catégories de utilisateurs : les super-utilisateurs, les
utilisateurs individuels, et les groupes. Les utilisateurs et les
super-utilisateurs sont authentifiés généralement par https. Les
groupes sont surtout des masques IP, mais rien n'empêche des
utilisateurs reconnus pas https d'être associés à un groupe. Chaque
catégorie est définie à l'aide d'un tableau. Les droits eux-mêmes sont
définis dans deux structures associatives (hachages), en faisant
correspondre à tout utilisateur et tout groupe déjà définis un tableau
composé de trois sous-tableaux -  un pour chaque
période définie. Les tableaux imbriqués contiennent les droits
explicitement décrits par des combinaisons des mots clés : all, none,
submit, simple_stats, all_stats etc.  Les dates de début et fin des
soumissions sont aussi données en arguments.

Voici un exemple d'appel du constructeur de SecurityAgent :


\begin{verbatim}
my $securisation = CGI::FOGE2::SecurityAgent->new
    (
     superusers  => ["root","admin"],
     users       => ["user1", "user2", "127.0.0.1"],
     user_rights => {
	 "user1" => [["none"],                             # étape 1
		      ["submit","simple_stats"],           # étape 2
		      ["all_stats"]],                      # étape 3

	 "user2" => [["none"],                 # étape 1
		     ["all_stats"],            # étape 2
		     ["all_stats"]],           # étape 3
	 
	 "127.0.0.1" =>  [["all"],["all"],["all"]]
	 },
     groups       => ["question_askers","replyers",
		      "gests", "195.137.127.0"],
     group_rights => {
	 "question_askers" => [["all"],           # étape 1
			       ["all_stats"],     # étape 2
			       ["all_stats"]],    # étape 3
	 "replyers"        =>  [["none"],
				["submit","simple_stats"],
				["simple_stats"]],
	 "gests"           => [["none"],
			       ["none"],
			       ["simple_stats"]],
	 "195.137.127.0"   =>  [["all"],["all"],["all"]]
	 },
     submit_date0 =>  ...,
     submit_date1 =>  ...,
     );

\end{verbatim}

L'authentification des utilisateurs se fait soit en analysant
seulement leurs adresses IP, soit en leur demandant de fournir un nom
de login et mot de passe, ceci fait automatiquement par le serveur
Apache, il suffit de lui procurer le fichier .htaccess contenant la
directive « require valid-user » dans le répertoire du script
générateur.

Pendant sa création, l'instance de SecurityAgent analysera le 'query
string' et effectuera un contrôle minimal, qui ne permettra pas aux
utilisateurs de n'exécuter que les actions qui leurs sont
permises. (De telle manière est résolu le problème de la version
précédente de Foge, qui permettait à un utilisateur malin de voir les
mots de passe pour la base de données).


\section{Conclusion}

D'un coté le travail réalisé nous a confronté à différentes problèmes
qu'on a su résoudre.

Par exemple le langage de programmation.
Perl étant un langage qui n'est pas adapté "à la lecture" (même avec
le souci d'écrire un code lisible et bien commenté), la compréhension
du fonctionnement de Foge a demandé un effort considérable (encore
plus pour Ognian Pertchev qui débutait en Perl!).
Une des raisons de choisir ce sujet de TER était
d'approfondir nos connaissances en PERL, BD et programmation CGI.

Et pour l'anecdote, on a même été confrontés à un bug dans Apache,
qu'on a par la suite, trouvé documenté à l'adresse 
"http://nagoya.apache.org/bugzilla/show\_bug.cgi?id=22030"

D'autre part le travail sur le TER représente pour nous une expérience
profitable. On a acquis une bonne maîtrise de Perl, Postgres et
Apache. On a su respecter les contraintes liées à la résolution d'un
problème concret (contrainte temporelle, de langage, d'intégration du
code). C'était aussi l'occasion de travailler en équipe - discuter,
combiner des différentes solutions, trouver la meilleure. Et
finalement on a eu la possibilité de travailler sur un "vrai"
logiciel, de le comprendre, de l'améliorer, et cela sous la direction
de son concepteur!


\end{document}
